import functools

from flask import jsonify, g, request, session

from case_convert import camel_case, snake_case

# 更新新旧的角色ID
from applications.extensions import db
from ..models import *

# 1：全部数据权限 2：自定数据权限 3：本部门数据权限 8：本部门及以下数据权限）
data_scope_constant = {
    "1": "全部数据权限",
    "2": "自定数据权限",
    "3": "本部门数据权限",
    "4": "本部门及以下数据权限",
}


def update_role_by_user_id(user_id, new_role_ids):
    """
    更新新旧的角色ID
    """
    # 查询当前用户的所有的角色

    # 增加角色
    # 删除角色
    pass


def update_dept_by_role_id(role_id, new_ids):
    """
    根据角色对应的岗位ID
    """
    old_ids = [item.dept_id for item in SysRoleDept.query.filter_by(role_id=role_id).all()]
    delete_ids = list(set(old_ids) - set(new_ids))
    add_ids = list(set(new_ids) - set(old_ids))
    delete_objects = SysRoleDept.query.filter_by(role_id=role_id).filter(SysRoleDept.dept_id.in_(delete_ids)).all()
    for item in delete_objects:
        db.session.delete(item)
    add_objects = [SysRoleDept(**{"role_id": role_id, "dept_id": item}) for item in add_ids]
    db.session.add_all(add_objects)
    db.session.commit()


# 根据角色对应的菜单ID
def update_menu_by_role_id(role_id, new_menu_ids):
    """
    根据角色对应的菜单ID
    """
    old_menu_ids = [item.menu_id for item in SysRoleMenu.query.filter_by(role_id=role_id).all()]
    delete_ids = list(set(old_menu_ids) - set(new_menu_ids))
    add_ids = list(set(new_menu_ids) - set(old_menu_ids))
    delete_objects = SysRoleMenu.query.filter_by(role_id=role_id).filter(SysRoleMenu.menu_id.in_(delete_ids)).all()
    for item in delete_objects:
        db.session.delete(item)
    add_objects = [SysRoleMenu(**{"role_id": role_id, "menu_id": item}) for item in add_ids]
    db.session.add_all(add_objects)
    db.session.commit()


# 接收参数处理
def request_snake_case_dict(data):
    if not isinstance(data, dict):
        raise Exception("data must be a dict")
    return {snake_case(item_k): item_v for item_k, item_v in data.items()}


# 返回数据转换
def response_camel_case_dict(data):
    if not isinstance(data, dict):
        raise Exception("data must be a dict")
    return {camel_case(item_k): item_v for item_k, item_v in data.items()}


def gen_routers(menu_list_top, menu_list):
    """
    前端左侧的路由菜单栏
    """

    def is_hidden(menu):
        return True if (menu.get("visible") == "1") else False

    def get_children(menu):
        current_menu_id = menu.get("menu_id")
        c_menu = []
        for item in menu_list:
            if item.get("parent_id") == current_menu_id:
                c_menu.append(item)
            else:
                pass
        return c_menu

    def build_menus_func(menu_li):
        routers = []
        for menu in menu_li:
            if menu.get("menu_type") == "M":

                if "0" == menu.get("is_frame"):
                    router = {
                        "name": menu.get("menu_name"),
                        "path": menu.get("path"),
                        "hidden": is_hidden(menu),
                        "component": None,
                        "meta": {
                            "title": menu.get("menu_name"),
                            "icon": menu.get("icon"),
                            "noCache": True,
                            "link": menu.get("path"),
                        },
                    }
                    routers.append(router)
                else:
                    if menu.get("parent_id") == 0:
                        router = {
                            "name": menu.get("path"),
                            "path": "/" + menu.get("path"),
                            "hidden": is_hidden(menu),
                            "redirect": "noRedirect",
                            "component": "Layout",
                            "alwaysShow": True,
                            "meta": {
                                "title": menu.get("menu_name"),
                                "icon": menu.get("icon"),
                                "noCache": False,
                                "link": None,
                            }
                        }
                    else:
                        router = {
                            "name": menu.get("path"),
                            "path": menu.get("path"),
                            "hidden": is_hidden(menu),
                            "redirect": "noRedirect",
                            "component": "ParentView",
                            "alwaysShow": True,
                            "meta": {
                                "title": menu.get("menu_name"),
                                "icon": menu.get("icon"),
                                "noCache": False,
                                "link": None,
                            }
                        }
                    c_menus = get_children(menu)
                    router["children"] = build_menus_func(c_menus)
                    routers.append(router)

            # 菜单
            if menu.get("menu_type") == "C":
                if menu.get("parent_id") == 0:
                    router = {
                        "path": "/",
                        "hidden": is_hidden(menu),
                        "component": "Layout",
                        "meta": None
                    }
                    children_list = []
                    children = {
                        "name": menu.get("path"),
                        "path": menu.get("path"),
                        "component": menu.get("component"),
                        "hidden": is_hidden(menu),
                        "meta": {
                            "title": menu.get("menu_name"),
                            "icon": menu.get("icon"),
                            "noCache": False,
                            "link": menu.get("path"),
                        }
                    }
                    children_list.append(children)
                    router["children"] = children_list
                else:
                    router = {
                        "name": menu.get("path"),
                        "path": menu.get("path"),
                        "component": menu.get("component"),
                        "hidden": is_hidden(menu),
                        "meta": {
                            "title": menu.get("menu_name"),
                            "icon": menu.get("icon"),
                            "noCache": False,
                            "link": menu.get("path"),
                        },
                    }
                routers.append(router)
        return routers

    return build_menus_func(menu_list_top)


# 获取到菜单的树形结构
def get_label_tree(menu_list):
    def get_children(menu):
        current_id = menu.get("id")
        c_menu = [item for item in menu_list if item.get("parent_id") == current_id]
        if c_menu:
            return c_menu
        else:
            pass

    def build_menu_func(menu_li):
        routers = []
        for menu in menu_li:
            router = {
                "id": menu.get("id"),
                "label": menu.get("label")
            }
            c_menus = get_children(menu)
            if c_menus:
                router["children"] = build_menu_func(c_menus)
            else:
                pass
            routers.append(router)
        return routers

    menu_list_top = [item for item in menu_list if item.get("parent_id") == 0]
    return build_menu_func(menu_list_top)


import time
import jwt


def get_token(username):
    token_dict = {'iat': int(time.time()),  # token的生成时间
                  'username': username,  # 自定义参数，用户名
                  'exp': int(time.time()) + 60 * 1000 * 24 * 7  # token的有效截至时间
                  }
    headers = {'alg': "HS256"}
    jwt_token = jwt.encode(token_dict,
                           "jwt",
                           algorithm='HS256',
                           headers=headers
                           )
    return jwt_token


# 定义解析token
def parse_token_v1():
    data = 'token 错误！'
    try:
        token = request.form['token']
        data = jwt.decode(token, 'jwt', algorithms=['HS256'])
        return data
    except:
        return data


# 定义解析token
def parse_token(token):
    data = 'token 错误！'
    try:
        data = jwt.decode(token, 'jwt', algorithms=['HS256'])
        return data
    except:
        return data


def admin_login_required(func):
    @functools.wraps(func)
    def inner(*args, **kwargs):
        user_token = request.headers.get('Authorization')
        if user_token:
            user_token = user_token[7:]
            g.token_info = parse_token(user_token)
            return func(*args, **kwargs)
        else:
            res_dict = {
                "code": 403,
                "msg": "未登录，请先登录"
            }
            return jsonify(res_dict)

    return inner


import bcrypt


# 生成密码
def gen_password():
    hashed2 = bcrypt.hashpw(password, bcrypt.gensalt(10, prefix=b"2a"))
    return hashed2


from datetime import datetime


# 保存对象
def save_objects(objects):
    for item in objects:
        if hasattr(item, "create_by"):
            item.create_by = session.get("user_name")
        if hasattr(item, "create_time"):
            item.create_time = datetime.now()

    db.session.add_all(objects)
    db.session.commit()


# 更新对象
def update_objects(objects):
    for item in objects:
        if hasattr(item, "update_by"):
            item.update_by = session.get("user_name")
        if hasattr(item, "update_time"):
            item.update_time = datetime.now()
        else:
            pass
    db.session.commit()


if __name__ == '__main__':
    password = "admin123"
    password = password.encode("utf-8")
    hashed = b"$2a$10$7JB720yubVSZvUI0rEqK/.VqGOZTH.ulu33dHOiBE8ByOhJIrdAu2"
    if bcrypt.checkpw(password, hashed):
        print("It Matches!")
    else:
        print("It Does not Match :(")
    hashed2 = bcrypt.hashpw(password, bcrypt.gensalt(10, prefix=b"2a"))
    print(hashed2)
